package com.ruoyi.aitcommon.api;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.code.kaptcha.Producer;
import com.ruoyi.aitapp.utils.APPConfigUtils;
import com.ruoyi.aitapp.utils.APPDataUtils;
import com.ruoyi.aitapp.utils.APPRuntimeManager;
import com.ruoyi.aitapp.vo.UserRunTimeVO;
import com.ruoyi.aitcommon.anotation.ApiLog;
import com.ruoyi.aitcommon.config.ConfigManager;
import com.ruoyi.aitcommon.utils.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.sign.Base64;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/ait/common/applogin")
public class APPLoginOperation {
    @Autowired
    ConfigManager configManager;
    @Autowired
    private APPRuntimeManager appRuntimeManager;
    @Autowired
    APPConfigUtils appConfigUtils;
    @Autowired
    private SysLoginService loginService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private SysPermissionService permissionService;
    @Autowired
    APPDataUtils appDataUtils;
    @Resource(name = "captchaProducer")
    private Producer captchaProducer;

    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;

    @Autowired
    private RedisCache redisCache;

    // 验证码类型
    @Value("${ruoyi.captchaType}")
    private String captchaType;

    @ApiLog("获取用户审批信息")
    @GetMapping("/getUserApproveList")
    public JSONObject getUserApproveList() {
        try{
            final List<Map<String, Object>> approveList = appRuntimeManager.getUserApproveInfo();
            return JSONResult.success(approveList);
        }
        catch (Exception ex){
            return JSONResult.error(ex);
        }
    }
    @ApiLog("获取使用用户清单")
    @GetMapping("/getUserList")
    public JSONObject getUserList() {
        try{
            final List<UserRunTimeVO> userInfoList = appRuntimeManager.getUserInfoList();
            return JSONResult.success(userInfoList);
        }
        catch (Exception ex){
            return JSONResult.error(ex);
        }
    }
    @ApiLog("获取授权菜单")
    @PostMapping("/getPermMenus")
    public JSONObject getPermMenus(@RequestBody String jsonstr) {
        JSONArray groups1=new JSONArray();
        try{
            //依据用户,获取授权菜单编码集合
            final JSONObject json = JSONUtils.parseObject(jsonstr);
            final String userCode = json.getString("userCode");
            ExceptionUtils.checkBlankOrUndefined(userCode,"用户编码为空");
            final List<Object> permMenus = appConfigUtils.getPermMenus(userCode);
            final List menuGroups = appConfigUtils.getMenuGroups(permMenus);
            return JSONResult.success(menuGroups);
        }catch (Exception ex){
            return JSONResult.error(ex);
        }
    }



    /**
     * APP登录
     * 同时校验ERP登录账号
     * @param loginBody
     * @return
     */
    @ApiLog("APP登录")
    @PostMapping("/login")
    public JSONObject login(@RequestBody LoginBody loginBody) {
        /**
         * 若依登录分析
         * 源文件 D:\java\workspace\ait\ruoyi-admin\src\main\java\com\ruoyi\web\controller\system\SysLoginController.java
         * 类 com.ruoyi.web.controller.system.SysLoginController.login
         * 访问地址 http://localhost:8080/login
         *
         * 若依登出分析
         * 登出是在配置类中配置登出成功后的处理类
         * 类 com.ruoyi.framework.config.SecurityConfig#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
         * 需要添加登出处理类，参考若依代码 com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl
         * 框架默认访问地址 http://localhost:8080/logout
         * 添加AIT登出类 com.ruoyi.aitcommon.config.AITLogoutSuccessHandler
         * 迁移类 SecurityConfig 至 com.ruoyi.aitcommon.config.SecurityConfig
         */
        try{
            //若依登录
            ExceptionUtils.checkBlankOrUndefined(loginBody.getUsername(),"用户名不能为空");
            String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                    loginBody.getUuid());
            //校验ERP登录
            String sql="select id,code,name,IsAlive isAlive,Effective_IsEffective isEffective " +
                    "from Base_User where code='%s'";
            sql=String.format(sql,loginBody.getUsername());
            final List<Map<String, Object>> dataList = appDataUtils.queryERP(sql);
            ExceptionUtils.checkBlankOrUndefined(dataList,"ERP不存在该用户[{}]",loginBody.getUsername());
            Map<String,Object> user=dataList.get(0);
            if(!user.get("isAlive").equals(true)||!user.get("isEffective").equals(true)){
                ExceptionUtils.throwException(null,"ERP用户[{}]已禁用",loginBody.getUsername());
            }
            //更新运行信息
            appRuntimeManager.initUserInfo(loginBody.getUsername());
            //处理返回值
            Map<String,Object> result=new LinkedHashMap<>();
            result.put(Constants.TOKEN, token);
            return JSONResult.success(result);
        }catch (Exception ex){
            return JSONResult.error(ex);
        }
    }

    /**
     * APP 返回用户信息,替换若依的返回登录信息
     * 该方法在APP登录成功后返回登录信息
     * @return
     */
    @GetMapping("/getInfo")
    public JSONObject getInfo()
    {
        /**
         * 若依登录分析
         * 源文件 D:\java\workspace\ait\ruoyi-admin\src\main\java\com\ruoyi\web\controller\system\SysLoginController.java
         * 类 com.ruoyi.web.controller.system.SysLoginController#getInfo()
         */
        try{
            //通过token获取用户信息
            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
            if(loginUser==null)
                throw new Exception("依据token获取用户为空");
            SysUser user = loginUser.getUser();
            // 角色集合
            Set<String> roles = permissionService.getRolePermission(user);
            // 权限集合
            Set<String> permissions = permissionService.getMenuPermission(user);
            Map<String,Object> result = new LinkedHashMap<>();
            result.put("user", user);
            result.put("roles", roles);
            result.put("permissions", permissions);
            return JSONResult.success(result);
        }catch (Exception ex){
            return JSONResult.error(ex);
        }
    }

    /**
     * 生成验证码
     */
    @GetMapping("/captchaImage")
    public JSONObject getCode(HttpServletResponse response) throws IOException
    {
        /**
         * 参考类 com.ruoyi.web.controller.common.CaptchaController#getCode(javax.servlet.http.HttpServletResponse)
         * 若依访问地址 http://localhost:8080/captchaImage
         */

        // 保存验证码信息
        String uuid = IdUtils.simpleUUID();
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;

        String capStr = null, code = null;
        BufferedImage image = null;

        // 生成验证码
        if ("math".equals(captchaType))
        {
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        }
        else if ("char".equals(captchaType))
        {
            capStr = code = captchaProducer.createText();
            image = captchaProducer.createImage(capStr);
        }

        redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try
        {
            ImageIO.write(image, "jpg", os);
        }
        catch (IOException e)
        {
//            return AjaxResult.error(e.getMessage());
            return JSONResult.error(e.getMessage());
        }

//        处理返回值
//        AjaxResult ajax = AjaxResult.success();
//        ajax.put("uuid", uuid);
//        ajax.put("img", Base64.encode(os.toByteArray()));
        Map<String,Object> ret=new LinkedHashMap<>();
        ret.put("uuid", uuid);
        ret.put("code", code);
        ret.put("capStr", capStr);
        ret.put("img", Base64.encode(os.toByteArray()));
        return JSONResult.success(ret);
    }
}
